﻿using com.iot.core.boot;
using com.iot.core.data;
using com.iot.core.data.entity;
using com.iot.core.data.service;
using com.iot.core.exception;
using com.iot.core.infrastructure;
using com.iot.core.manager.id;
using com.iot.ht.Controllers.htmenu.data;
using com.iot.ht.Controllers.htpage.data;
using com.iot.ht.Controllers.htrole.data;
using com.iot.ht.Controllers.htuser.data;
using Icom.iot.core.ext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace com.iot.ht.Controllers.htrole.service
{
    public class HtRoleService : BaseService<HtRole>, IHtRoleService
    {       
        readonly IRepository<HtPlat> htPlatMapper;
        readonly IHtRoleMenuService htRoleMenuService;
        readonly IRepository<HtDept> htDeptMapper;
        public HtRoleService(IRepository<HtPlat> p1 ,
            IHtRoleMenuService p2,
            IRepository<HtDept> p3
            ) 
        {
            htPlatMapper = p1;
            htRoleMenuService = p2;
            htDeptMapper = p3;
        }

        public async Task<Page<HtRoleDto>> PageAsync(BasePageDtQto qm)
        {
            var DB = BaseMapper.DB;
            var q = BaseMapper.GetAll()
                .Join(DB.Set<HtUser>(),
                    a => new { CrtUid = a.CrtUid  },
                    b => new { CrtUid = b.Id },
                    (a, b) => new
                    {
                        Data = a,

                        CrtUname =b.Name
                    }
                )
                .Join(DB.Set<HtDept>(),
                     a => new { CrtDid = a.Data.CrtDid },
                    b => new { CrtDid = b.Id },
                    (a, b) => new
                    {
                        Data = a.Data,
                        CrtUname = a.CrtUname,
                        CrtDname = b.Name
                    }
                )
                .Join(DB.Set<HtPlat>(),
                     a => new { HtplatId = a.Data.HtplatId },
                    b => new { HtplatId = b.Id },
                    (a, b) => new
                    {
                        Data = a.Data,
                        CrtUname = a.CrtUname,
                        CrtDname = a.CrtDname,
                        HtplatName=b.Name
                    }
                );
            if (!string.IsNullOrEmpty(qm.Key))
            {
                q = q.Where(a => a.Data.Name.Contains(qm.Key)
                 
                );
            }
            if (!string.IsNullOrWhiteSpace(qm.Dtb))
            {
                q = q.Where(a => a.Data.CrtDt >= qm.GetDB());
            }
            if (!string.IsNullOrWhiteSpace(qm.Dte))
            {
                q = q.Where(a => a.Data.CrtDt < qm.GetDE());
            }
            var sort = qm.GetSort();
            sort.Filed = "Data." + sort.Filed;

            

            var Total = await q.CountAsync();
            var r = new Page<HtRoleDto>(Total, qm.Page, qm.PageSize);

            q = q.OrderBy(sort.Filed, sort.Asc);
            var l = await q.Skip((qm.Page - 1) * qm.PageSize).Take(qm.PageSize).ToListAsync();

            r.Records = new List<HtRoleDto>();
            foreach (var m in l)
            {
                var mm = new HtRoleDto();
                EntityToDto(m.Data, mm);
                mm.CrtUname = m.CrtUname;
                mm.CrtDname = m.CrtDname;
                mm.HtplatName = m.HtplatName;
                r.Records.Add(mm);
            }
            return r;
        }
        public HtRoleDto InsertInit()
        {
            var mm = new HtRoleDto();

            var mplat = htPlatMapper.GetById(1000L);
            mm.HtplatId=mplat.Id;   
            mm.HtplatName=mplat.Name;
            return mm;
        }
        

        public async Task<HtRoleDto> DetailAsync(BaseQto qm)
        {
            var m = await BaseMapper.GetByIdAsync(qm.Id);
            var mm = new HtRoleDto();

            BaseMapper.EntityToDto(m, mm);
            mm.CrtUname = BaseMapper.GetName(m.CrtUid, "htuser");
            mm.CrtDname = BaseMapper.GetName(m.CrtDid, "htdept");
            mm.HtplatName = BaseMapper.GetName(m.HtplatId, "htplat");
            var lmenuid = await htRoleMenuService.GetRolesMenuIdsAsync(new List<long> { mm.Id });
            mm.HtmenuIds = lmenuid;
            return mm;
        }
        public int Insert(HtRoleDto mm)
        { 
            var m = new HtRole();
            BaseMapper.DtoToEntity(mm, m);
             
            foreach(var masrc in  mm.HtmenuIds)
            {
                var madst = new HtRoleMenu
                {
                    Id = HtIdManager.Current.NextLong(),
                    HtroleId = m.Id,
                    HtmenuId = masrc
                };
                htRoleMenuService.Insert(madst, true,false);
            }

            return  Insert(m);
        }
        public int Update(HtRoleDto mm)
        {
            var m = GetById(mm.Id);
                   
            BaseMapper.DtoToEntity(mm, m);


            var ldbauth = htRoleMenuService.GetAll()
                .Where(a => a.HtroleId == m.Id).ToList();
             
            foreach (var masrc in mm.HtmenuIds)
            {
                var madst = ldbauth.Where(a => a.HtmenuId == masrc).FirstOrDefault();
                if (madst == null)
                {
                     madst = new HtRoleMenu
                     {
                         Id = HtIdManager.Current.NextLong(),
                         HtroleId = m.Id,
                         HtmenuId = masrc
                     };
                    htRoleMenuService.Insert(madst, true, false);
                }
 
            }

            foreach(var madb in ldbauth)
            {
                var masrc = mm.HtmenuIds.Where(a => a == madb.HtmenuId).Count();
                if (masrc == 0)
                {
                    htRoleMenuService.Delete(madb, true,false);
                }
            }
            return Update(m);
        }
        public List<IdNameDto> ListByDeptId(BaseQto mm)
        {
            var mdept = htDeptMapper.GetById(mm);
            var r = BaseMapper.GetAll()
                .Where(a => a.HtplatId == mdept.HtplatId)
                .OrderBy(a => a.Id)
                .Select(a => new IdNameDto { Id = a.Id, Name = a.Name })
                .ToList();
            return r;
        }
    }
}
